home *** CD-ROM | disk | FTP | other *** search
/ The Programmer Disk / The Programmer Disk (Microforum).iso / xpro / c4 / pro20 / libpbm5.c < prev    next >
C/C++ Source or Header  |  1990-05-31  |  9KB  |  427 lines

  1. /* libpbm5.c - pbm utility library part 5
  2. **
  3. ** Copyright (C) 1988 by Jef Poskanzer.
  4. **
  5. ** Permission to use, copy, modify, and distribute this software and its
  6. ** documentation for any purpose and without fee is hereby granted, provided
  7. ** that the above copyright notice appear in all copies and that both that
  8. ** copyright notice and this permission notice appear in supporting
  9. ** documentation.  This software is provided "as is" without express or
  10. ** implied warranty.
  11. */
  12.  
  13. #include <stdio.h>
  14. #include "pbm.h"
  15. #include "rast.h"
  16.  
  17. /*
  18. ** Semi-work-alike versions of some Sun pixrect routines.  Just enough
  19. ** for rasterfile reading and writing to work.
  20. */
  21.  
  22. struct pixrect *
  23. mem_create( w, h, depth )
  24. int w, h, depth;
  25.     {
  26.     struct pixrect *p;
  27.     struct mpr_data *m;
  28.  
  29.     p = (struct pixrect *) malloc( sizeof(struct pixrect) );
  30.     if ( p == NULL )
  31.     return NULL;
  32.     p->pr_ops = NULL;
  33.     p->pr_size.x = w;
  34.     p->pr_size.y = h;
  35.     p->pr_depth = depth;
  36.     m = p->pr_data = (struct mpr_data *) malloc( sizeof(struct mpr_data) );
  37.     if ( m == NULL )
  38.     {
  39.     free( p );
  40.     return NULL;
  41.     }
  42.     /* According to the documentation, linebytes is supposed to be rounded
  43.     ** up to a longword (except on 386 boxes).  However, this turns out
  44.     ** not to be the case.  In reality, all of Sun's code rounds up to
  45.     ** a short, not a long.
  46.     */
  47.     m->md_linebytes = ( w * depth + 15 ) / 16 * 2;
  48.     m->md_offset.x = 0;
  49.     m->md_offset.y = 0;
  50.     m->md_flags = 0;
  51.     m->md_image = (unsigned char *) malloc( m->md_linebytes * h );
  52.     if ( m->md_image == NULL )
  53.     {
  54.     free( m );
  55.     free( p );
  56.     return NULL;
  57.     }
  58.  
  59.     return p;
  60.     }
  61.  
  62. void
  63. mem_free( p )
  64. struct pixrect *p;
  65.     {
  66.     free( p->pr_data->md_image );
  67.     free( p->pr_data );
  68.     free( p );
  69.     }
  70.  
  71. int
  72. pr_dump( p, out, colormap, type, copy_flag )
  73. struct pixrect *p;
  74. FILE *out;
  75. colormap_t *colormap;
  76. int type, copy_flag;
  77.     {
  78.     struct rasterfile h;
  79.     int size, besize, count;
  80.     unsigned char *beimage, *bp, c, pc;
  81.     int i, j;
  82.  
  83.     h.ras_magic = RAS_MAGIC;
  84.     h.ras_width = p->pr_size.x;
  85.     h.ras_height = p->pr_size.y;
  86.     h.ras_depth = p->pr_depth;
  87.  
  88.     h.ras_type = type;
  89.     switch ( type )
  90.     {
  91.     case RT_OLD:
  92.     pm_error( "old rasterfile type is not supported", 0,0,0,0,0 );
  93.  
  94.     case RT_STANDARD:
  95.     h.ras_length = p->pr_size.y * p->pr_data->md_linebytes;
  96.     break;
  97.  
  98.     case RT_BYTE_ENCODED:
  99.     size = p->pr_size.y * p->pr_data->md_linebytes;
  100.     bp = p->pr_data->md_image;
  101.     beimage = (unsigned char *) malloc( size * 3 / 2 );    /* worst case */
  102.     if ( beimage == NULL )
  103.         return PIX_ERR;
  104.     besize = 0;
  105.     count = 0;
  106.     for ( i = 0; i < size; ++i )
  107.         {
  108.         c = *bp++;
  109.         if ( count > 0 )
  110.         {
  111.         if ( pc != c )
  112.             {
  113.             if ( count == 1 && pc == 128 )
  114.             {
  115.             beimage[besize++] = 128;
  116.             beimage[besize++] = 0;
  117.             count = 0;
  118.             }
  119.             else if ( count > 2 || pc == 128 )
  120.             {
  121.             beimage[besize++] = 128;
  122.             beimage[besize++] = count - 1;
  123.             beimage[besize++] = pc;
  124.             count = 0;
  125.             }
  126.             else
  127.             {
  128.             for ( j = 0; j < count; ++j )
  129.                 beimage[besize++] = pc;
  130.             count = 0;
  131.             }
  132.             }
  133.         }
  134.         pc = c;
  135.         ++count;
  136.         if ( count == 256 )
  137.         {
  138.         beimage[besize++] = 128;
  139.         beimage[besize++] = count - 1;
  140.         beimage[besize++] = c;
  141.         count = 0;
  142.         }
  143.         }
  144.     if ( count > 0 )
  145.         {
  146.         if ( count == 1 && c == 128 )
  147.         {
  148.         beimage[besize++] = 128;
  149.         beimage[besize++] = 0;
  150.         }
  151.         if ( count > 2 || c == 128 )
  152.         {
  153.         beimage[besize++] = 128;
  154.         beimage[besize++] = count - 1;
  155.         beimage[besize++] = c;
  156.         }
  157.         else
  158.         {
  159.         for ( j = 0; j < count; ++j )
  160.             beimage[besize++] = c;
  161.         }
  162.         }
  163.     h.ras_length = besize;
  164.     break;
  165.  
  166.     default:
  167.     pm_error( "unknown rasterfile type", 0,0,0,0,0 );
  168.     }
  169.  
  170.     if ( colormap == NULL )
  171.     {
  172.     h.ras_maptype = RMT_NONE;
  173.     h.ras_maplength = 0;
  174.     }
  175.     else
  176.     {
  177.     h.ras_maptype = colormap->type;
  178.     switch ( colormap->type )
  179.         {
  180.         case RMT_EQUAL_RGB:
  181.         h.ras_maplength = colormap->length * 3;
  182.         break;
  183.  
  184.         case RMT_RAW:
  185.         h.ras_maplength = colormap->length;
  186.         break;
  187.  
  188.         default:
  189.         pm_error( "unknown colormap type", 0,0,0,0,0 );
  190.         }
  191.     }
  192.  
  193.     if ( pm_writebiglong( out, h.ras_magic ) == -1 )
  194.     return PIX_ERR;
  195.     if ( pm_writebiglong( out, h.ras_width ) == -1 )
  196.     return PIX_ERR;
  197.     if ( pm_writebiglong( out, h.ras_height ) == -1 )
  198.     return PIX_ERR;
  199.     if ( pm_writebiglong( out, h.ras_depth ) == -1 )
  200.     return PIX_ERR;
  201.     if ( pm_writebiglong( out, h.ras_length ) == -1 )
  202.     return PIX_ERR;
  203.     if ( pm_writebiglong( out, h.ras_type ) == -1 )
  204.     return PIX_ERR;
  205.     if ( pm_writebiglong( out, h.ras_maptype ) == -1 )
  206.     return PIX_ERR;
  207.     if ( pm_writebiglong( out, h.ras_maplength ) == -1 )
  208.     return PIX_ERR;
  209.  
  210.     if ( colormap != NULL )
  211.     {
  212.     switch ( colormap->type )
  213.         {
  214.         case RMT_EQUAL_RGB:
  215.         if ( fwrite( colormap->map[0], 1, colormap->length, out ) !=
  216.          colormap->length )
  217.         return PIX_ERR;
  218.         if ( fwrite( colormap->map[1], 1, colormap->length, out ) !=
  219.          colormap->length )
  220.         return PIX_ERR;
  221.         if ( fwrite( colormap->map[2], 1, colormap->length, out ) !=
  222.          colormap->length )
  223.         return PIX_ERR;
  224.         break;
  225.  
  226.         case RMT_RAW:
  227.         if ( fwrite( colormap->map[0], 1, colormap->length, out ) !=
  228.          colormap->length )
  229.         return PIX_ERR;
  230.         break;
  231.         }
  232.     }
  233.  
  234.     switch ( type )
  235.     {
  236.     case RT_STANDARD:
  237.     if ( fwrite( p->pr_data->md_image, 1, h.ras_length, out ) !=
  238.          h.ras_length )
  239.         return PIX_ERR;
  240.     break;
  241.  
  242.     case RT_BYTE_ENCODED:
  243.     if ( fwrite( beimage, 1, besize, out ) != besize )
  244.         {
  245.         free( beimage );
  246.         return PIX_ERR;
  247.         }
  248.     free( beimage );
  249.     break;
  250.     }
  251.  
  252.     return 0;
  253.     }
  254.  
  255. int
  256. pr_load_header( in, hP )
  257. FILE *in;
  258. struct rasterfile *hP;
  259.     {
  260.     if ( pm_readbiglong( in, &(hP->ras_magic) ) == -1 )
  261.     return PIX_ERR;
  262.     if ( hP->ras_magic != RAS_MAGIC )
  263.     return PIX_ERR;
  264.     if ( pm_readbiglong( in, &(hP->ras_width) ) == -1 )
  265.     return PIX_ERR;
  266.     if ( pm_readbiglong( in, &(hP->ras_height) ) == -1 )
  267.     return PIX_ERR;
  268.     if ( pm_readbiglong( in, &(hP->ras_depth) ) == -1 )
  269.     return PIX_ERR;
  270.     if ( pm_readbiglong( in, &(hP->ras_length) ) == -1 )
  271.     return PIX_ERR;
  272.     if ( pm_readbiglong( in, &(hP->ras_type) ) == -1 )
  273.     return PIX_ERR;
  274.     if ( pm_readbiglong( in, &(hP->ras_maptype) ) == -1 )
  275.     return PIX_ERR;
  276.     if ( pm_readbiglong( in, &(hP->ras_maplength) ) == -1 )
  277.     return PIX_ERR;
  278.     return 0;
  279.     }
  280.  
  281. int
  282. pr_load_colormap( in, hP, colormap )
  283. FILE *in;
  284. struct rasterfile *hP;
  285. colormap_t *colormap;
  286.     {
  287.     if ( colormap == NULL || hP->ras_maptype == RMT_NONE )
  288.     {
  289.     char junk[30000];
  290.  
  291.     if ( fread( junk, 1, hP->ras_maplength, in ) != hP->ras_maplength )
  292.         return PIX_ERR;
  293.     }
  294.     else
  295.     {
  296.     colormap->type = hP->ras_maptype;
  297.     switch ( hP->ras_maptype )
  298.         {
  299.         case RMT_EQUAL_RGB:
  300.         colormap->length = hP->ras_maplength / 3;
  301.         colormap->map[0] = (unsigned char *) malloc( colormap->length );
  302.         if ( colormap->map[0] == NULL )
  303.         return PIX_ERR;
  304.         colormap->map[1] = (unsigned char *) malloc( colormap->length );
  305.         if ( colormap->map[1] == NULL )
  306.         {
  307.         free( colormap->map[0] );
  308.         return PIX_ERR;
  309.         }
  310.         colormap->map[2] = (unsigned char *) malloc( colormap->length );
  311.         if ( colormap->map[2] == NULL )
  312.         {
  313.         free( colormap->map[0] );
  314.         free( colormap->map[1] );
  315.         return PIX_ERR;
  316.         }
  317.         if ( fread( colormap->map[0], 1, colormap->length, in ) != colormap->length ||
  318.              fread( colormap->map[1], 1, colormap->length, in ) != colormap->length ||
  319.              fread( colormap->map[2], 1, colormap->length, in ) != colormap->length )
  320.         {
  321.         free( colormap->map[0] );
  322.         free( colormap->map[1] );
  323.         free( colormap->map[2] );
  324.         return PIX_ERR;
  325.         }
  326.         break;
  327.  
  328.         case RMT_RAW:
  329.         colormap->length = hP->ras_maplength;
  330.         colormap->map[0] = (unsigned char *) malloc( colormap->length );
  331.         if ( colormap->map[0] == NULL )
  332.         return PIX_ERR;
  333.         colormap->map[2] = colormap->map[1] = colormap->map[0];
  334.         if ( fread( colormap->map[0], 1, hP->ras_maplength, in ) != hP->ras_maplength )
  335.         {
  336.         free( colormap->map[0] );
  337.         return PIX_ERR;
  338.         }
  339.         break;
  340.  
  341.         default:
  342.         pm_error( "unknown colormap type", 0,0,0,0,0 );
  343.         }
  344.     }
  345.     return 0;
  346.     }
  347.  
  348. struct pixrect *
  349. pr_load_image( in, hP, colormap )
  350. FILE *in;
  351. struct rasterfile *hP;
  352. colormap_t *colormap;
  353.     {
  354.     struct pixrect *p;
  355.     unsigned char *beimage;
  356.     register unsigned char *bep, *bp, c;
  357.     int i;
  358.     register int j, count;
  359.  
  360.     p = mem_create( hP->ras_width, hP->ras_height, hP->ras_depth );
  361.     if ( p == NULL )
  362.     return NULL;
  363.  
  364.     switch ( hP->ras_type )
  365.     {
  366.     case RT_OLD:
  367.     pm_error( "old rasterfile type is not supported", 0,0,0,0,0 );
  368.  
  369.     case RT_STANDARD:
  370.     if ( fread( p->pr_data->md_image, 1, hP->ras_length, in ) !=
  371.          hP->ras_length )
  372.         {
  373.         mem_free( p );
  374.         return NULL;
  375.         }
  376.     break;
  377.  
  378.     case RT_BYTE_ENCODED:
  379.     beimage = (unsigned char *) malloc( hP->ras_length );
  380.     if ( beimage == NULL )
  381.         {
  382.         mem_free( p );
  383.         return NULL;
  384.         }
  385.     if ( fread( beimage, 1, hP->ras_length, in ) != hP->ras_length )
  386.         {
  387.         mem_free( p );
  388.         free( beimage );
  389.         return NULL;
  390.         }
  391.     bep = beimage;
  392.     bp = p->pr_data->md_image;
  393.     for ( i = 0; i < hP->ras_length; )
  394.         {
  395.         c = *bep++;
  396.         if ( c == 128 )
  397.         {
  398.         count = ( *bep++ ) + 1;
  399.         if ( count == 1 )
  400.             {
  401.             *bp++ = 128;
  402.             i += 2;
  403.             }
  404.         else
  405.             {
  406.             c = *bep++;
  407.             for ( j = 0; j < count; ++j )
  408.             *bp++ = c;
  409.             i += 3;
  410.             }
  411.         }
  412.         else
  413.         {
  414.         *bp++ = c;
  415.         ++i;
  416.         }
  417.         }
  418.     free( beimage );
  419.     break;
  420.  
  421.     default:
  422.     pm_error( "unknown rasterfile type", 0,0,0,0,0 );
  423.     }
  424.  
  425.     return p;
  426.     }
  427.